//
//  StepCollectionViewFlowLayout.swift
//  HeadlineNews
//
//  Created by han on 2019/7/1.
//  Copyright © 2019 han. All rights reserved.
//

import UIKit



class StepCollectionViewFlowLayout: UICollectionViewFlowLayout {
    // 滑动CollectionView时，cell的位置
    override func targetContentOffset(forProposedContentOffset proposedContentOffset: CGPoint, withScrollingVelocity velocity: CGPoint) -> CGPoint {
        // 目的：修改最终的contentOffset，从而实现cell的在界面的最终位置。
        // 在这个方法中，我们经常用到的一些属性方法：
        // self.layoutAttributesForElements(in: proposedRect) 获取到预估Rect内的所有UICollectionViewLayoutAttributes cell的信息 可以获取到这些尺寸信息加以利用.
        // UICollectionViewLayoutAttributes: 可以拿到大小尺寸，形变；可以拿到类型cell/supplementaryView/decorationView
        // 一般经常用到的是中心点比较
        
        guard let collectionView = self.collectionView else { return proposedContentOffset }
        
        // 获取预估显示的Rect （因为当前是横向滚动的，所以y设置为0）
        let propesedRect = CGRect(x: proposedContentOffset.x, y: 0, width: collectionView.bounds.width, height: collectionView.bounds.height)
        // 获取预估可视的cell的 attributes 数组
        guard let layoutAttributes: [UICollectionViewLayoutAttributes] = super.layoutAttributesForElements(in: propesedRect) else { return proposedContentOffset }
       
        let visiableCenterX = collectionView.bounds.midX
        
        // 当前逻辑时，选中一个放在collectionView的正中间
        var candidateAttributes: UICollectionViewLayoutAttributes?
        
        for attributes in layoutAttributes {
            
            if attributes.representedElementCategory != .cell {
                continue;
            }
            
            if candidateAttributes == nil {
                candidateAttributes = attributes
                continue
            }
            
            // 比较哪一个更靠近中心点
            if abs(attributes.center.x - visiableCenterX) < abs(candidateAttributes!.center.x - visiableCenterX) {
                candidateAttributes = attributes
            }
        }
        // 拿到最中间的那一个layoutAttributes
        guard let aCandidateAttributes = candidateAttributes else { return proposedContentOffset }
        
        // 拿到新的offset
        var newOffsetX = aCandidateAttributes.center.x - collectionView.bounds.size.width / 2
        
        // 下面开始处理velocity 滑动时，是存在速度的
        // 有可能，偏移速度和偏移距离是同向的的，也有可能是反向的。
        
        // 计算的offset与当前collectionView的offset比较
        let offset = newOffsetX - collectionView.contentOffset.x
        // 速度向右，但是实际的相左，则向
        if (velocity.x < 0 && offset > 0) || (velocity.x > 0 && offset < 0) {
            let pageWidth = itemSize.width + minimumLineSpacing
            newOffsetX += velocity.x > 0 ? pageWidth : -pageWidth
        }
        
        return CGPoint(x: newOffsetX, y: proposedContentOffset.y)
    }
    
}
